接下來繼續前篇未完成的部分
首先是Url,在大多數的狀況下都會是用String來設定
所以就額外加入一個擴充方法叫SetUrl
    public static HttpRequestMessageBuilder SetUrl(
        this HttpRequestMessageBuilder builder,
        string url)
    {
        builder.SetUrl(url.ToUrl());
        return builder;
    }
    internal static Uri ToUrl(this string url)
         => new Uri(url);
再來是HttpMethod,同樣的較多狀況會使用字串來定義
所以同樣也用一個擴充方法來完成
    public static HttpRequestMessageBuilder SetMethod(
        this HttpRequestMessageBuilder builder, 
        string method)
    {
        builder.SetMethod(method.ToHttpMethod());
        return builder;
    }
    internal static HttpMethod ToHttpMethod(this string method)
        => new HttpMethod(method);
接下來Content 比較常見的兩個實作 String 和 Stream 也是各自建立自己的方法
    public static HttpRequestMessageBuilder SetContent(
        this HttpRequestMessageBuilder builder,
        string content)
    {
        builder.SetContent(content.ToHttpContent());
        return builder;
    }
    internal static HttpContent ToHttpContent(this string str)
        => new StringContent(str);
    public static HttpRequestMessageBuilder SetContent(
        this HttpRequestMessageBuilder builder, 
        Stream content)
    {
        builder.SetContent(content.ToHttpContent());
        return builder;
    }
    internal static HttpContent ToHttpContent(this Stream stream)
        => new StreamContent(stream);
Header的內容過多,他甚至可以額外在新建立一組Builder
所以就用前面常用的設定法來完成
    public static HttpRequestMessageBuilder SetHeaderBy(
        this HttpRequestMessageBuilder builder, 
        Action<HttpRequestHeaders> config)
    {
        if(config == null) return builder;
        builder.ConfigureHeader(config);
        return builder;
    }
而最後再用一個輔助的方法來達成讓Builder可以被連續設定
    public static HttpRequestMessageBuilder SetBy(
        this HttpRequestMessageBuilder builder,
        Action<HttpRequestMessageBuilder> config)
    {
        config?.Invoke(builder);
        return builder;
    }
因此,Cralwer引用這樣的方法的方式就會是
    public static Task<IHtmlElementCollection> GetByAsync(
        this ICrawler crawler,
        Action<HttpRequestMessageBuilder> config)
        => crawler.GetAsync(new HttpRequestMessageBuilder()
                .SetBy(config)
                .Build(CreateHttpRequestMessage))
            .ToCollectionsAsync();
所以就可以達成這次主題的目的
    crawler.GetAsync(ConfigureRequest);
    public void ConfigureRequest(HttpRequestMessageBuilder req)
        => req.SetUrl("https://localhost/api")
            .SetMethod("Post")
            .SetContent(JsonConvert.SerializeObject(entitiy))
            .SetHeaderBy(ConfigureRequestHeader);
    public void ConfigureRequestHeader(HttpRequestHeader header)
        =>header.CacheControl
            .SetBy(ConfigureHeaderCacheControl);
    public void ConfigureHeaderCacheControl(CacheControlHeaderValue cache)
        => cache.NoCache = true;
繞了那麼遠,看看是否有達成目標,方法很簡單
跟著程式碼念一次看看對不對就知道了
    // 爬蟲用設定的Request已非同步尋找 html集合 (FindByAsync的 return value)
    crawler.FindByAsync(ConfigureRequest);
    public void ConfigureRequest(HttpRequestMessageBuilder req)
            // 設置url 為 https://localhost/api 
        => req.SetUrl("https://localhost/api")
            // 設置HttpMethod 為 Post
            .SetMethod("Post")
            // 設置內容為 json 序列化 entity 的內容
            .SetContent(JsonConvert.SerializeObject(entitiy))
            // 用 ConfigureRequestHeader來設定 Header
            .SetHeaderBy(ConfigureRequestHeader);
    public void ConfigureRequestHeader(HttpRequestHeader header)
            // 用ConfigureHeaderCacheControl來設定 CacheControl
        =>header.CacheControl.SetBy(ConfigureHeaderCacheControl);
    public void ConfigureHeaderCacheControl(CacheControlHeaderValue cache)
            // 設定cache 的 NoCache為true
        => cache.NoCache = true;
整理文字如下
    內容大綱:
    爬蟲用設定的 Request 已非同步尋找 html 集合 (FindByAsync 的 return value)
    
    內容細節:
    設置 url 為 https://localhost/api 
    設置 HttpMethod 為 Post
    設置內容為 json 序列化 entity 的內容
    用 ConfigureRequestHeader 來設定 Header
    用 ConfigureHeaderCacheControl 來設定 CacheControl
    設定cache 的 NoCache為 true
如此一來外部也可以接得很清楚